#include "mqtt_dev.h"
#include "portCtrl.h"
#include "healthCheck.h"

#define EXAMPLE_ESP_MQTT_HOST "mqtt://39.105.62.98"
#define MyMqttHost1_RECV      "/MNIAS/BLOCK001/recv"
#define MyMqttHost1_SEND      "/MNIAS/BLOCK001/send"
#define KEY_phrases           "PHRASES:"
#define KEY_beep              "BEEP:"
#define KEY_health            "HEALTH"

char phrasesNum = 0; // 快捷短语编号

static const char *TAG = "MQTT";
int mqtt_msg_id; // mqtt消息ID

static void log_error_if_nonzero(const char *message, int error_code)
{
    if (error_code != 0) {
        ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
    }
}
/*
 * @brief Event handler registered to receive MQTT events
 *
 *  This function is called by the MQTT client event loop.
 *
 * @param handler_args user data registered to the event.
 * @param base Event base for the handler(always MQTT Base in this example).
 * @param event_id The id for the received event.
 * @param event_data The data for the event, esp_mqtt_event_handle_t.
 */
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;

    switch ((esp_mqtt_event_id_t)event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");

            mqtt_msg_id = esp_mqtt_client_publish(client, MyMqttHost1_SEND, "LINK:online,", 0, 1, 0);
            ESP_LOGI(TAG, "LED state upload successful, msgid=%d", mqtt_msg_id);

            mqtt_msg_id = esp_mqtt_client_subscribe(client, MyMqttHost1_RECV, 1);
            ESP_LOGI(TAG, "sent subscribe successful, msgid=%d", mqtt_msg_id);

            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;
        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msgid=%d", event->msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msgid=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msgid=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            char *temp = (char *)malloc(event->data_len); // 动态创建
            sprintf(temp, "%.*s", event->data_len, event->data); // 定长赋值
            if(strstr(temp, KEY_phrases) != NULL)
            {
                phrasesNum = atoi(strstr(temp, KEY_phrases) + strlen(KEY_phrases));
                PORTCtrlClass.vibrationNum += 2;
                printf("MQTT: received phrases num %d\n", phrasesNum);
            }
            else if(strstr(temp, KEY_beep) != NULL)
            {
                PORTCtrlClass.beepNum = atoi(strstr(temp, KEY_beep) + strlen(KEY_beep));
                printf("MQTT: received beep num %d\n", PORTCtrlClass.beepNum);
            }
            else if(strstr(temp, KEY_health) != NULL)
            {
                char p[45];
                memset(p, '\0', 45);
                sprintf((char *)p, "RATE:%d,SPO:%d,BK:%d,HIGH:%d,LOW:%d,", HealthClass.HealthData.heartRate, HealthClass.HealthData.spo, HealthClass.HealthData.bk, HealthClass.HealthData.rsv[3], HealthClass.HealthData.rsv[4]);
                esp_mqtt_client_publish(client, MyMqttHost1_SEND, p, 0, 1, 0);
                printf("MQTT: send health data to client\n");
            }
            // printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            // printf("DATA=%.*s\r\n", event->data_len, event->data);
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
                log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
                log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
                log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
                ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));

            }
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
}

void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .uri = EXAMPLE_ESP_MQTT_HOST,
    };
#if CONFIG_BROKER_URL_FROM_STDIN
    char line[128];

    if (strcmp(mqtt_cfg.uri, "FROM_STDIN") == 0) {
        int count = 0;
        printf("Please enter url of mqtt broker\n");
        while (count < 128) {
            int c = fgetc(stdin);
            if (c == '\n') {
                line[count] = '\0';
                break;
            } else if (c > 0 && c < 127) {
                line[count] = c;
                ++count;
            }
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
        mqtt_cfg.uri = line;
        printf("Broker url: %s\n", line);
    } else {
        ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
        abort();
    }
#endif /* CONFIG_BROKER_URL_FROM_STDIN */

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
    esp_mqtt_client_start(client);
}